;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 介绍：	【51单片机汇编】用Keil模拟器查看IO口输出
; NOTE:		File format: UTF-8
; 备注：	1、复位和中断运行起始地址介绍详见STC官方文档《STC89C52系列单片机器件手册》
;			第6章 中断系统；
;			2、CSEG等所有Keil汇编伪指令的含义详见Keil安装目录下的文档
;			Keil_v5\C51\Hlp\a51.chm，文档里支持搜索；
;			3、8051 CPU内核的寄存器含义的介绍可参考大学的单片机原理等课程，也可以看
;			STC官方文档《STC89C52系列单片机器件手册》;只想看原版8051指令集文档，
;			不想看教材的话，可以搜索下载“Atmel 8051 Microcontrollers Hardware Manual”，
;			或者“MCS ® 51 Family of Microcontrollers Architectural Overview”；
;			本Git仓库doc文件夹内有上述文档的下载链接；
;			4、本工程默认使用Keil模拟器运行，无需硬件，按F7编译后，按Ctrl+F5开始
;			运行，在Keil软件的Logic Analyzer模拟示波器窗口中看IO口输出结果；
; 查看方法：
;			1、本工程中已配置好窗口，但工程刚打开时该示波器窗口并未展示出来，需要
;			先按F7编译，再按Ctrl+F5开始运行，再点击Stop按钮停止运行，点击Keil软件
;			上方菜单的View-->Analysis Windows-->Logic Analyzer让示波器窗口出现，
;			然后将该窗口向下拉长一点，好看到P0口的那一行内容，刚出现时波形太密
;			不好观察，需要将鼠标放在Logic Analyzer窗口的P0波形上，按住电脑键盘的
;			Ctrl键，然后向前滚动鼠标滚轮，放大波形后即可看到P0.0IO口输出的矩形波；
;			2、如果你不是打开本文件夹下已下载的工程，而是自己创建的工程，则还需要配置
;			采样的IO口，点击Logic Analyzer窗口的Setup，在弹出窗口中点击右边X叉叉左边的图标New(Insert)
;			-->在出来的输入栏里输入P0.0并回车，然后鼠标在刚刚出现的P0这一行上点一下，
;			然后在Max:文本输入框内将0xFF改成1，然后点击该弹出窗口的Close，
;			然后按F5运行程序，然后点击Stop按钮停止运行，则能在Keil虚拟示波器
;			的P0栏看到输出的矩形波；
;			3、Keil模拟器中示波器部分的详细功能介绍在Keil软件安装目录Keil_v5\UV4\uv4.chm
;			文件中的Debugging-->Debug Windows and Dialogs-->Logic Analyzer章节，
;			网上可以参考的操作文章有：
;			https://www.doc88.com/p-0344855977193.html
;			https://blog.csdn.net/weixin_54089068/article/details/121781168
;			https://blog.csdn.net/weixin_43737995/article/details/98049869
; 作者		将狼才鲸
; 日期		2023-06-10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; 包含寄存器定义头文件，也可以用#include <REGISTERS51.INC>，同样有效
$INCLUDE(REGISTERS51.INC)

	;;
	; 1、ORG的作用和CSEG AT的作用一样，指定后面代码在内存中存放的位置，
	; CSEG等是Keil开发环境的伪指令（其它编译器如开源的SDCC可能有不一样的伪指令）;
	; 2、十六进制立即数以H结尾
	ORG		0000H	; RAM的0地址是复位中断执行的入口，后面的一些地址是各中断的入口
	LJMP	RESET	; 长跳转指令可跳64KB内的地址（函数），类似的还有其它短跳的指令

	ORG		0003H	; 外部中断0
	LJMP	DEFAULT_INT

	ORG		000BH	; 定时器0
	LJMP	DEFAULT_INT

	ORG		0013H	; 外部中断1
	LJMP	DEFAULT_INT

	ORG		001BH	; 定时器1
	LJMP	DEFAULT_INT

	ORG		0023H	; 外部中断2
	LJMP	DEFAULT_INT

	ORG		002BH	; 外部中断3
	LJMP	DEFAULT_INT

	; 标号以冒号:结尾，和C语言的函数名类似
RESET:	
	NOP	; 空指令，消耗一个时钟周期的时间，什么也不做

LOOP:	; 汇编函数不遇到RET指令的话会一直往后执行，所以RESET这个主程序会进入下面的死循环
	NOP
	NOP
	SETB P0.0	; 置位，P0.0（P0寄存器的第0位） IO口输出高电平
	NOP
	NOP
	CLR P0.0	; 位清零，P0.0 IO口输出低电平
	LJMP	LOOP

DEFAULT_INT:
	NOP
	RETI

	END ; 汇编文件必须以END结尾
